#include <stdint.h>
#include <functional>
#include <sys/epoll.h>
class EventLoop;
class Channel
{
private:
    using EventCallback = std::function<void()>;

private:
    int _fd;
    EventLoop *_loop;
    uint32_t _events;  // 当前需要监控的事件
    uint32_t _revents; // 当前连接触发的事件
    using EventCallback = std::function<void()>;
    EventCallback _read_callback;
    EventCallback _write_callback;
    EventCallback _close_callback;
    EventCallback _error_callback;
    EventCallback _event_callback;

public:
    Channel(EventLoop *loop, int fd) : _loop(loop),
                                       _fd(fd),
                                       _events(0),
                                       _revents(0) {}
    void Update();
    void Remove();
    int Fd()
    {
        return _fd;
    }
    uint32_t Events()
    {
        return _events;
    }
    void SetRevents(uint32_t revents)
    {
        _revents = revents;
    }
    void SetReadCallBack(const EventCallback &cb)
    {
        _read_callback = cb;
    }
    void SetWriteCallBack(const EventCallback &cb)
    {
        _write_callback = cb;
    }
    void SetErrorCallBack(const EventCallback &cb)
    {
        _error_callback = cb;
    }
    void SetCloseCallBack(const EventCallback &cb)
    {
        _close_callback = cb;
    }
    void SetEventCallBack(const EventCallback &cb)
    {
        _event_callback = cb;
    }
    bool ReadAble()
    {
        return (_events & EPOLLIN);
    }
    bool WriteAble()
    {
        return (_events & EPOLLOUT);
    }
    void DisableRead()
    {
        _events & ~EPOLLIN;
        Update();
    }
    void DisableWrite()
    {
        _events & ~EPOLLOUT;
        Update();
    }
    void DisableAll()
    {
        _events = 0;
        Update();
    }
    void EnableRead()
    {
        _events |= EPOLLIN;
        Update();
    }
    void EnableWrite()
    {
        _events |= EPOLLOUT;
        Update();
    }
    void HandleEvent()
    {
        if ((_revents & EPOLLIN) || (_revents & EPOLLRDHUP) || (_revents & EPOLLPRI))
        {
            if (_read_callback)
            {
                _read_callback();
            }
        }
        if (_revents & EPOLLOUT)
        {
            if (_write_callback)
            {
                _write_callback();
            }
        }
        else if (_revents & EPOLLERR)
        {
            if (_error_callback)
            {
                _error_callback();
            }
        }
        else if (_revents & EPOLLHUP)
        {
            if (_close_callback)
            {
                _close_callback();
            }
        }
        if (_event_callback)
        {
            _event_callback();
        }
    }
};